package com.bing.task.v1;

import com.bing.Constant;
import com.bing.Utils;
import com.bing.entity.Account;
import com.bing.entity.Note;
import com.bing.entity.Review;
import com.bing.entity.Status;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.RecursiveTask;

/**
 * Created by Administrator on 15-11-7.
 */
public class FetchAndParseNoteReview extends RecursiveTask<AccountResult> {
    private static final int TASK_NUM = 10;
    private static final Logger LOGGER = LoggerFactory.getLogger(FetchAndParseNoteReview.class);
    private List<Account> accounts;


    public FetchAndParseNoteReview(List<Account> accounts) {
        this.accounts = accounts;
    }

    @Override
    protected AccountResult compute() {
        if (accounts.size() <= TASK_NUM) {
            LOGGER.info("开始任务...............................");
            AccountResult accountResult = new AccountResult();


            for (Account account : accounts) {
                if(account.getUid()==0){
                    account.setStatus(Status.OK);
                    continue;
                }
              //  accountResult.getQuestions().addAll(parseIds(account));
                accountResult.getNotes().addAll(parseNote(account));
                accountResult.getReviews().addAll(parseReview(account));
                Utils.getAccount(account);
            }

            accountResult.getAccounts().addAll(accounts);
            return accountResult;
        } else {
            FetchAndParseNoteReview left = new FetchAndParseNoteReview(accounts.subList(0, accounts.size() / 2));
            FetchAndParseNoteReview right = new FetchAndParseNoteReview(accounts.subList(accounts.size() / 2, accounts.size()));
            left.fork();
            right.fork();
            AccountResult leftResult = left.join();
            AccountResult rightResult = right.join();
            return leftResult.join(rightResult);
        }

    }

    private Set<Integer> parseIds(Account account) {
        Set<Integer> question = new HashSet<Integer>();
        try {
            LOGGER.info("parseIds....................{}",account.getUid());
            question.addAll(Utils.fetchMyQuestionsAnswer("question", account.getUid()));
            question.addAll(Utils.fetchMyQuestionsAnswer("answer", account.getUid()));
            if (question.size() != 0) {
                File dir = Paths.get(Constant.BASE_PATH, "account", String.valueOf(account.getUid())).toFile();
                if (!dir.exists()) {
                    dir.mkdirs();
                }
                StringBuilder sb = new StringBuilder();
                for (Integer integer : question) {
                    sb.append(integer + "\n");
                }
                Files.write(Paths.get(Constant.BASE_PATH, "account", String.valueOf(account.getUid()), "ids.txt"), sb.toString().getBytes(), StandardOpenOption.CREATE);
                account.setIdStatus(Status.OK);
                LOGGER.info("question ids sum:{},uid:{}", question.size(),account.getUid());
            }
        } catch (Exception e) {
            account.setIdStatus(Utils.handleException(e));
            LOGGER.error("", e.getMessage());
        }
        return question;
    }

    private List<Review> parseReview(Account account) {
        List<Review> reviews = new ArrayList<Review>();
        if(account.getReviewStatus()==Status.OK){
            return reviews;
        }
        try {
            LOGGER.info("parse Review.................{}",account.getUid());
            String review = Utils.fetchReview(account.getUid());
            if (review != null) {
                File dir = Paths.get(Constant.BASE_PATH, "account", String.valueOf(account.getUid())).toFile();
                if (!dir.exists()) {
                    dir.mkdirs();
                }
                Files.write(Paths.get(Constant.BASE_PATH, "account", String.valueOf(account.getUid()), "review.html"), review.getBytes(), StandardOpenOption.CREATE);
            }
            reviews = Utils.parse2Reviews(account.getUid(), review);
            account.setReviews(reviews.size());
            account.setReviewStatus(Status.OK);
            LOGGER.info("parseReview sum:{}, uid:{}", reviews.size(),account.getUid());
        } catch (Exception e) {
            LOGGER.error("parse review:{}异常:", account.getUid(), e.getMessage());
            account.setReviewStatus(Utils.handleException(e));
        }
        return reviews;
    }

    private List<Note> parseNote(Account account) {

        List<Note> notes = new ArrayList<Note>();
        if(account.getNoteStatus()==Status.OK){
            return notes;
        }
        try {
            LOGGER.info("parse Note.................{}",account.getUid());
            Path notePath = Paths.get(Constant.BASE_PATH, "account", String.valueOf(account.getUid()), "note.html");
            String note = Utils.fetchNote(account.getUid());
            if (note != null) {
                File dir = Paths.get(Constant.BASE_PATH, "account", String.valueOf(account.getUid())).toFile();
                if (!dir.exists()) {
                    dir.mkdirs();
                }
                Files.write(notePath, note.getBytes(), StandardOpenOption.CREATE);
                notes = Utils.parse2Notes(account.getUid(), note);
                account.setNotes(notes.size());
                account.setNoteStatus(Status.OK);
                LOGGER.info("parseNote sum:{},uid:{}", notes.size(),account.getUid());

            }
        } catch (Exception e) {
            LOGGER.error("parse note:{}异常{}", account.getUid(), e.getMessage());
            account.setNoteStatus(Utils.handleException(e));
        }
        return notes;
    }

}
